package com.avecsys.quotemanager.utils;

import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import javax.faces.context.FacesContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.avecsys.quotemanager.constants.ApplicationConstants;
import com.avecsys.quotemanager.dao.common.EnumActor;
import com.avecsys.quotemanager.dao.common.EnumTransactionStatus;
import com.avecsys.quotemanager.exception.BaseException;
import com.avecsys.quotemanager.mbeans.core.MessageBoardMBean;

/**
 * @author Sam Sundar K
 * 
 */
public class MessageBoardUtil {

	private static final Log log = LogFactory.getLog(MessageBoardUtil.class);

	/**
	 * 
	 * @param transactionStatus
	 * @param actor
	 */
	public static void publishTransactionStatusMessage(
			TransactionStatus transactionStatus, EnumActor actor,
			String messageBoardId, String msgKey, Object msgParamValues[]) {
		FacesContext facesContext = FacesContext.getCurrentInstance();
		String bundleName = ApplicationConstants.RESOURCE_BUNDLE_TRANSACTION;
		if (transactionStatus.getStatus().intValue() == EnumTransactionStatus.BUSINESS_FLOW_FAIL
				.ordinal()) {
			bundleName = ApplicationConstants.RESOURCE_BUNDLE_ERROR;
		}
		ResourceBundle bundle = getResourceBundle(facesContext, bundleName);
		String formatedMessage = getFormattedMessage(transactionStatus, actor,
				msgParamValues, bundle);
		MessageBoardMBean messageBoardMBean = getMessageBoardMBean(facesContext);
		messageBoardMBean.reset();
		if (transactionStatus.getStatus().intValue() == EnumTransactionStatus.READ_SUCCESS
				.ordinal()
				|| transactionStatus.getStatus().intValue() == EnumTransactionStatus.SAVE_SUCESS
						.ordinal()
				|| transactionStatus.getStatus().intValue() == EnumTransactionStatus.UPDATE_SUCCESS
						.ordinal()
				|| transactionStatus.getStatus().intValue() == EnumTransactionStatus.DELETE_SUCCESS
						.ordinal()) {
			messageBoardMBean.getInfoList().add(formatedMessage);
		} else if (transactionStatus.getStatus().intValue() == EnumTransactionStatus.READ_FAIL
				.ordinal()
				|| transactionStatus.getStatus().intValue() == EnumTransactionStatus.SAVE_FAIL
						.ordinal()
				|| transactionStatus.getStatus().intValue() == EnumTransactionStatus.UPDATE_FAIL
						.ordinal()
				|| transactionStatus.getStatus().intValue() == EnumTransactionStatus.DELETE_FAIL
						.ordinal()
				|| transactionStatus.getStatus().intValue() == EnumTransactionStatus.OPTIMIST_LOCK_FAIL
						.ordinal()) {
			messageBoardMBean.getErrorList().add(formatedMessage);
		} else {
			messageBoardMBean.getWarnList().add(formatedMessage);
		}
	}

	private static MessageBoardMBean getMessageBoardMBean(
			FacesContext facesContext) {
		MessageBoardMBean messageBoardMBean = (MessageBoardMBean) facesContext
				.getApplication().evaluateExpressionGet(facesContext,
						"#{messageBoardMBean}", MessageBoardMBean.class);
		return messageBoardMBean;
	}

	/**
	 * Method to translate the BaseException sub types and publish to user
	 * screen
	 * 
	 * @param e
	 *            SubClass of BaseException instance
	 */
	public static void publishException(Exception e) {
		FacesContext facesContext = FacesContext.getCurrentInstance();
		if (e instanceof BaseException) {
			BaseException exception = (BaseException) e;
			ResourceBundle bundle = getResourceBundle(facesContext,
					ApplicationConstants.RESOURCE_BUNDLE_ERROR);
			String errorMessage = bundle.getString(exception.getErrorCode());
			MessageFormat messageFormat = new MessageFormat(errorMessage);
			String formatedMessage = messageFormat.format(exception
					.getErrorCodeArgs());
			MessageBoardMBean messageBoardMBean = getMessageBoardMBean(facesContext);
			if (exception.getSeverity() == BaseException.SEVERITY_ERROR) {
				messageBoardMBean.getErrorList().add(formatedMessage);
			} else if (exception.getSeverity() == BaseException.SEVERITY_WARN) {
				messageBoardMBean.getWarnList().add(formatedMessage);
			} else if (exception.getSeverity() == BaseException.SEVERITY_INFO) {
				messageBoardMBean.getInfoList().add(formatedMessage);
			}
		} else {
			// TODO:
		}
	}

	/**
	 * Method to push a message to the message board based
	 * 
	 * @param severity
	 * @param messageBoardId
	 * @param msgKey
	 * @param msgParamValues
	 */
	public static void publishMessage(String bundleName, int severity,
			String messageBoardId, String msgKey, Object msgParamValues[]) {
		FacesContext facesContext = FacesContext.getCurrentInstance();
		ResourceBundle bundle = getResourceBundle(facesContext, bundleName);
		String message = bundle.getString(msgKey);
		MessageFormat messageFormat = new MessageFormat(message);
		String formatedMessage = messageFormat.format(msgParamValues);
		MessageBoardMBean messageBoardMBean = getMessageBoardMBean(facesContext);
		if (severity == BaseException.SEVERITY_ERROR) {
			messageBoardMBean.getErrorList().add(formatedMessage);
		} else if (severity == BaseException.SEVERITY_WARN) {
			messageBoardMBean.getWarnList().add(formatedMessage);
		} else if (severity == BaseException.SEVERITY_INFO) {
			messageBoardMBean.getInfoList().add(formatedMessage);
		}
	}

	/**
	 * @param transactionStatus
	 * @param actor
	 * @param msgParamValues
	 * @param bundle
	 * @return
	 */
	private static String getFormattedMessage(
			TransactionStatus transactionStatus, EnumActor actor,
			Object[] msgParamValues, ResourceBundle bundle) {
		String paramActorValue = null;
		String message = null;
		String formatedMessage = null;
		if (transactionStatus.getStatus().intValue() == EnumTransactionStatus.BUSINESS_FLOW_FAIL
				.ordinal()) {
			formatedMessage = bundle
					.getString(transactionStatus.getErrorCode());
		} else {
			paramActorValue = bundle.getString(actor.getActor());
			message = bundle.getString("TNX_STATUS_"
					+ transactionStatus.getStatus());
			Object messageParams[] = null;
			if (msgParamValues == null) {
				messageParams = new Object[1];
			} else {
				messageParams = new Object[msgParamValues.length + 1];
			}
			messageParams[0] = paramActorValue;
			if (msgParamValues != null) {
				for (int i = 0; i < msgParamValues.length; i++) {
					messageParams[i + 1] = msgParamValues[i];
				}
			}
			MessageFormat messageFormat = new MessageFormat(message);
			formatedMessage = messageFormat.format(messageParams);
		}
		return formatedMessage;
	}

	public static ResourceBundle getResourceBundle(FacesContext facesContext,
			String bundleName) {
		ResourceBundle resourceBundle = facesContext.getApplication()
				.getResourceBundle(facesContext, bundleName);
		return resourceBundle;
	}

	/**
	 * Static Method to reset all the messages in message board
	 */
	public static void resetMessageBoard() {
		FacesContext facesContext = FacesContext.getCurrentInstance();
		MessageBoardMBean messageBoardMBean = getMessageBoardMBean(facesContext);
		messageBoardMBean.reset();
	}

	public static String getValue(FacesContext facesContext, String bundleName,
			String key, Object args[]) {
		ResourceBundle resourceBundle = getResourceBundle(facesContext,
				bundleName);
		String messageKey = "#" + key + "#";
		try {
			messageKey = resourceBundle.getString(key);
			if (args != null && args.length > 0) {
				MessageFormat messageFormat = new MessageFormat(messageKey);
				messageKey = messageFormat.format(args);
			}
		} catch (MissingResourceException mre) {
			log.error(mre);
		}
		return messageKey;
	}
}
